package com.lfy.chat.listener;

import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONUtil;
import com.lfy.chat.domain.bo.VerifyMsgBo;
import com.lfy.chat.domain.msg.UnOlineEventFriend;
import com.lfy.chat.domain.msg.UnOlineEventMsg;
import com.lfy.chat.domain.msg.VerityEventRead;
import com.lfy.chat.domain.ws.UnOlineMsg;
import com.lfy.chat.domain.ws.resp.FriendResp;
import com.lfy.common.constant.ChatReidsConstant;
import com.lfy.common.constant.GlobalConstant;
import com.lfy.common.enums.ChatEnum;
import com.lfy.commons.utils.JsonUtils;
import com.lfy.commons.utils.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.*;

/**
 * 离线消息事件处理器
 *
 * @author <a href="https://www.lvfeiy.top">吕飞扬</a>
 * @date 2023/10/24 20:25
 */
@Component
@Slf4j
public class UnOlineMsgListener {

    @EventListener(classes = UnOlineEventMsg.class)
    @Async
    public void sendUnOlineSingleMsg(UnOlineEventMsg msg) {
        String from = msg.getFrom();
        String to = msg.getTo();
        String text = msg.getText();
        String key = ChatReidsConstant.CHAT_SINGLE_PREFIX.concat(to);
        UnOlineMsg unOlineMsg = new UnOlineMsg();
        unOlineMsg.setFrom(from);
        unOlineMsg.setText(text);
        unOlineMsg.setDate(DateUtil.formatChineseDate(new Date(), false, true));
        synchronized (GlobalConstant.UN_OLINE_SINGLE_LOCK_PREFIX.concat(to).intern()) {
            Boolean hasKey = RedisUtil.hHasKey(key, from);
            if (hasKey) {
                Object json = RedisUtil.hget(key, from);
                System.out.println(json);
                List<UnOlineMsg> msgs = JSONUtil.parseArray((String) json).toList(UnOlineMsg.class);
                msgs.add(unOlineMsg);
                RedisUtil.hset(key, from, JSONUtil.toJsonStr(msgs));
            } else {
                ArrayList<UnOlineMsg> list = new ArrayList<>();
                list.add(unOlineMsg);
                RedisUtil.hset(key,from,JSONUtil.toJsonStr(list));
            }
        }

    }

    @EventListener(classes = UnOlineEventFriend.class)
    @Async
    public void addFriendMsg(UnOlineEventFriend unOlineEventFriend){
        FriendResp friendResp = unOlineEventFriend.getFriendResp();
        String to = unOlineEventFriend.getTo();
        RedisUtil.lSet(ChatReidsConstant.CHAT_FRIEND_PREFIX.concat(to),friendResp);
    }

    @EventListener(classes = VerityEventRead.class)
    public void verifyChangeRead(VerityEventRead read){

        String key = read.getKey();
        Set<String> ids = read.getIds();
        List<String> waitRemove = new ArrayList<>();
        List<VerifyMsgBo> waitInsert = new ArrayList<>();
        synchronized (GlobalConstant.VERIFY_LOCK.concat(read.get_LOCK_ID()).intern()){
            Set<String> strings = RedisUtil.sGet(key);
            if(CollectionUtils.isEmpty(strings)){
                log.error("in verifyChangeRead() error,Redis key:{} is null",key);
                return;
            }
            for (String string : strings) {
                VerifyMsgBo verifyMsgBo = JsonUtils.toObj(string, VerifyMsgBo.class);
                if(ids.contains(verifyMsgBo.getVeryMsgId())){
                    waitRemove.add(string);
                    verifyMsgBo.setIsRead(ChatEnum.read.getType());
                    waitInsert.add(verifyMsgBo);
                }
            }
            RedisUtil.setRemove(key,waitRemove.toArray());
            RedisUtil.sSet(key,waitInsert.toArray());
        }

    }
    private Map<String, String> buildMap(String from, UnOlineMsg unOlineMsg) {
        ArrayList<UnOlineMsg> list = new ArrayList<>();
        list.add(unOlineMsg);
        Map<String, String> map = new HashMap<>();
        return map;
    }


}
